package com.bp.hearthealth.pulse.lnapps.bp_ui.bp_activity.bp_blood_pressure

import android.content.Intent
import android.text.Editable
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
import androidx.lifecycle.Observer
import com.anythink.core.api.ATAdInfo
import com.anythink.core.api.AdError
import com.anythink.interstitial.api.ATInterstitial
import com.app.hubert.guide.NewbieGuide
import com.app.hubert.guide.core.Controller
import com.app.hubert.guide.listener.OnGuideChangedListener
import com.app.hubert.guide.model.GuidePage
import com.app.hubert.guide.model.HighLight
import com.app.hubert.guide.model.HighlightOptions
import com.app.hubert.guide.model.RelativeGuide
import com.bp.hearthealth.pulse.lnapps.R
import com.bp.hearthealth.pulse.lnapps.ads.admob.interstitial_ad.AdMobInterstitialAdListener
import com.bp.hearthealth.pulse.lnapps.ads.admob.interstitial_ad.AdMobInterstitialAdManager
import com.bp.hearthealth.pulse.lnapps.ads.admob.native_ad.AdMobNativeAdListener
import com.bp.hearthealth.pulse.lnapps.ads.admob.native_ad.AdMobNativeAdManager
import com.bp.hearthealth.pulse.lnapps.ads.model.AdsSwitch
import com.bp.hearthealth.pulse.lnapps.ads.topon.banner_ad.TopOnBannerAdManager
import com.bp.hearthealth.pulse.lnapps.ads.topon.banner_ad.TopOnBannerAdListener
import com.bp.hearthealth.pulse.lnapps.ads.topon.interstitial_ad.TopOnInterAdManager
import com.bp.hearthealth.pulse.lnapps.ads.topon.interstitial_ad.listener.manual_load.TopOnInterstitialAdListener
import com.bp.hearthealth.pulse.lnapps.appsflyer.AppsFlyerUtils
import com.bp.hearthealth.pulse.lnapps.base.BpBaseActivity
import com.bp.hearthealth.pulse.lnapps.base.bp_liveDataBus.BpLiveDataBus
import com.bp.hearthealth.pulse.lnapps.bp_extension.LogUtil
import com.bp.hearthealth.pulse.lnapps.bp_extension.UIHelperBp
import com.bp.hearthealth.pulse.lnapps.bp_ui.bp_activity.bp_blood_pressure.bp_report.BloodPressureResultActivity
import com.bp.hearthealth.pulse.lnapps.bp_ui.bp_dialog.BpBloodPressureDetailDialog
import com.bp.hearthealth.pulse.lnapps.bp_ui.bp_dialog.BpKeyboardPopupWindow
import com.bp.hearthealth.pulse.lnapps.bp_ui.bp_dialog.BpTimerPickerDialog
import com.bp.hearthealth.pulse.lnapps.bp_utils.AfterTextChangedListener
import com.bp.hearthealth.pulse.lnapps.bp_utils.Constants
import com.bp.hearthealth.pulse.lnapps.bp_utils.DateUtils
import com.bp.hearthealth.pulse.lnapps.bp_utils.LimitInputTextWatcher
import com.bp.hearthealth.pulse.lnapps.bp_utils.SpUtils
import com.bp.hearthealth.pulse.lnapps.bp_utils.throttleClick
import com.bp.hearthealth.pulse.lnapps.databinding.ActivityBloodPressureNewRecordBgBinding
import com.google.android.gms.ads.nativead.NativeAd
import com.gyf.immersionbar.ImmersionBar
import com.hjq.toast.Toaster
import org.koin.androidx.viewmodel.ext.android.viewModel


class BpBloodPressureNewRecordActivity : BpBaseActivity<ActivityBloodPressureNewRecordBgBinding>() {

    private var nativeAd: NativeAd? = null
    private val viewModel: BpBloodPressureViewModel by viewModel()
    private lateinit var popupWindow: BpKeyboardPopupWindow
    private lateinit var bloodPressureDetailDialog: BpBloodPressureDetailDialog
    private var controller: Controller? = null
    private var toponBannerManager: TopOnBannerAdManager? = null

    override fun initData() {
        super.initData()
        //New Record页展示
        AppsFlyerUtils.trackEvent("bp_new_show")
        binding.lifecycleOwner = this
        binding.viewModel = viewModel
        if (!AdsSwitch.getBoolean(AdsSwitch.adInterCacheControl)) {
            TopOnInterAdManager.initManualLoadInterstitialAd(this)
            TopOnInterAdManager.manualLoadAd()
        }
        registerObserver()

//        loadAdmobNativeAd()
//        loadTopOnNativeAd()
        toponBannerManager = TopOnBannerAdManager()
        //原生接入后需要删除showGuide()这个方法
        showGuide()

        if (SpUtils.getBoolean("guide_two")) {
            toponBannerManager!!.initBannerView(this)
            loadTopOnBannerAd()
        }
        SpUtils.saveBoolean("guide_two", true)

        viewModel.initDate()
        val note = SpUtils.getString("note_str")
        if (!note.isNullOrEmpty()) {
            viewModel.note.set(note)
        }
    }

    private fun loadTopOnBannerAd() {
        if (toponBannerManager?.getBannerView() != null) {
            if (toponBannerManager?.getBannerView()?.checkAdStatus()?.isReady == true) {
                LogUtil.iTopOn("TopOn 【横幅广告】 BpBloodPressureNewRecordActivity isReady")
                setTopOnBannerView()
            } else {
                toponBannerManager?.setBannerListener(object : TopOnBannerAdListener {
                    override fun onBannerShow(entity: ATAdInfo) {
                        LogUtil.iTopOn("TopOn 【横幅广告】 BpBloodPressureNewRecordActivity onBannerShow")
                    }

                    override fun onBannerLoaded() {
                        LogUtil.iTopOn("TopOn 【横幅广告】 BpBloodPressureNewRecordActivity onBannerLoaded")
                        setTopOnBannerView()
                    }
                })
            }
        }
    }

    private fun setTopOnBannerView() {
        toponBannerManager?.getBannerView()?.setBannerAdListener(null)
        toponBannerManager?.setBannerListener(null)
        binding.bannerAdContainer.visibility = View.VISIBLE
        binding.bannerAdContainer.removeAllViews()
        binding.bannerAdContainer.addView(
            toponBannerManager?.getBannerView(),
            FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                binding.bannerAdContainer.layoutParams.height
            )
        )
    }

    private fun registerObserver() {
        viewModel.insertBloodPressureResult.observe(this, Observer { result ->
            val id = result.getOrNull()
            if (id == null) {
                Toaster.show(result.exceptionOrNull())
                result.exceptionOrNull()?.printStackTrace()
                return@Observer
            }
            SpUtils.saveString("note_str", viewModel.note.get())
            LogUtil.i("插入成功：id为 $id")
            BpLiveDataBus.with<Boolean>(Constants.REFRESH_TRACKER).postData(true)
//            loadAdmobInsertAd(id)
            loadTopOnInsertAd(id)
        })
    }

    private fun loadTopOnInsertAd(vararg id: String) {
        TopOnInterAdManager.setManualLoadListener(object : TopOnInterstitialAdListener {
            override fun onFireBaseAdIsClosed() {
                LogUtil.iTopOn("插页广告Firebase中关闭了。。。。。。。。")
                startJumpActivity(id)
            }

            override fun onInterstitialAdShow(entity: ATAdInfo) {

            }
//            override fun onInterstitialAdLoaded() {
//                LogUtil.iTopOn("插页广告 onInterstitialAdLoaded 回调")
//                if (TopOnInterAdManager.isAdReady()) {
//                    TopOnInterAdManager.mInterstitialAd!!.show(this@BpBloodPressureNewRecordActivity)
//                } else {
//                    TopOnInterAdManager.setManualLoadListener(null)
//                    startJumpActivity(id)
//                }
//            }

            override fun onInterstitialAdClose(entity: ATAdInfo) {
                TopOnInterAdManager.setManualLoadListener(null)
                startJumpActivity(id)
            }

            override fun onInterstitialAdLoadFail(adError: AdError) {
                TopOnInterAdManager.setManualLoadListener(null)
                startJumpActivity(id)
            }

            override fun onInterstitialAdVideoError(adError: AdError) {
                TopOnInterAdManager.setManualLoadListener(null)
                startJumpActivity(id)
            }

            override fun onNotReady() {
                TopOnInterAdManager.setManualLoadListener(null)
                startJumpActivity(id)
            }
        })
        TopOnInterAdManager.showInterstitialAd(this)
    }

    override fun initListener() {
        super.initListener()
        binding.apply {
            tvSave.throttleClick { saveBloodPressure() }
            tvNote.throttleClick { showKeyboardPopupWindow() }
            editSystolic.addTextChangedListener(
                LimitInputTextWatcher(
                    editSystolic,
                    Constants.CANNOT_START_ZORE,
                    object : AfterTextChangedListener {
                        override fun afterTextChanged(editable: Editable) {
                            this@BpBloodPressureNewRecordActivity.viewModel.apply {
                                if (editable.toString().isEmpty()) {
                                    systolic.set("120")
                                } else {
                                    systolic.set(editable.toString())
                                }
                                refreshSysAndDia()
                            }

                        }
                    })
            )
            editDiastolic.addTextChangedListener(
                LimitInputTextWatcher(
                    editDiastolic,
                    Constants.CANNOT_START_ZORE,
                    object : AfterTextChangedListener {
                        override fun afterTextChanged(editable: Editable) {
                            this@BpBloodPressureNewRecordActivity.viewModel.apply {
                                if (editable.toString().isEmpty()) {
                                    diastolic.set("80")
                                } else {
                                    diastolic.set(editable.toString())
                                }
                                refreshSysAndDia()
                            }
                        }
                    })
            )
            editPulse.addTextChangedListener(
                LimitInputTextWatcher(
                    editPulse,
                    Constants.CANNOT_START_ZORE,
                    object : AfterTextChangedListener {
                        override fun afterTextChanged(editable: Editable) {}
                    })
            )
            constraintDate.throttleClick { showTimerPicker(Constants.TYPE_DATE) }
            constraintTime.throttleClick { showTimerPicker(Constants.TYPE_TIME) }
            ivDetial.throttleClick {
                if (!this@BpBloodPressureNewRecordActivity::bloodPressureDetailDialog.isInitialized) {
                    bloodPressureDetailDialog = BpBloodPressureDetailDialog(activity!!)
                }
                bloodPressureDetailDialog.showDialog()
            }
        }
    }

    private fun saveBloodPressure() {
        viewModel.insertBloodPressure(
            Constants.USER_ID,
            DateUtils.timestampToyyyyMMdd(viewModel.saveTimeMillis.value!!.toLong()).toLong(),
            viewModel.saveTimeMillis.value!!.toLong(),
            binding.editSystolic.text.toString(),
            binding.editDiastolic.text.toString(),
            binding.editPulse.text.toString(),
            viewModel.enumStatus.value!!
        )
    }

    private fun showKeyboardPopupWindow() {
        if (!this::popupWindow.isInitialized) {
            popupWindow = BpKeyboardPopupWindow(this)
            popupWindow.init()
        }
        popupWindow.setOnInputListener(object : BpKeyboardPopupWindow.OnInputListener {
            override fun onInput(inputText: String) {
                viewModel.note.set(inputText)
            }
        })
        popupWindow.show(binding.constraintLayout)
    }

    private fun showTimerPicker(type: String) {
        BpTimerPickerDialog(activity!!,
            type,
            UIHelperBp.getString(R.string._date_str),
            Constants.monthList,
            object : BpTimerPickerDialog.TimePickerCallback {
                override fun setDate(
                    year: String,
                    month: String,
                    day: String,
                    hour: String,
                    minute: String,
                    type: String
                ) {
                    if (type == Constants.TYPE_DATE) {
                        viewModel.apply {
                            cacheDateStr.value = "${year}${month}${day}"
                            showDate.value = DateUtils.timestampToDate(
                                DateUtils.dateTimeStringToTimestamp(
                                    "${cacheDateStr.value}${cacheTimeStr.value}", "yyyyMMddHH:mm"
                                ), Constants.TIME_STYLE
                            )
                            saveTimeMillis.value = DateUtils.dateTimeStringToTimestamp(
                                "${cacheDateStr.value}${cacheTimeStr.value}", "yyyyMMddHH:mm"
                            )
                        }
                    } else {
                        viewModel.apply {
                            showTime.value = ("${hour}:${minute}")
                            cacheTimeStr.value = ("${hour}:${minute}")
                            saveTimeMillis.value = DateUtils.dateTimeStringToTimestamp(
                                "${cacheDateStr.value}${cacheTimeStr.value}", "yyyyMMddHH:mm"
                            )
                        }
                    }
                }
            }).show()
    }


    override fun initImmersionBar() {
        super.initImmersionBar()
        binding.includeNewRecord.apply {
            tvBack.text = UIHelperBp.getString(R.string._new_record_str)
            tvBack.setOnClickListener {
//                loadAdmobInsertAd()
                loadTopOnInsertAd()
            }
            ImmersionBar.with(this@BpBloodPressureNewRecordActivity).titleBar(toolbar).init()
        }
    }

    /**
     *  ○ 点击Back入口，展示插页广告
     *     ■ 插页广告资源加载到，立即展示，广告关闭后自动跳转至上一级页面
     *     ■ 插页广告资源未加载到，自动跳转至上一级页面
     *
     *  ○ 点击Save按钮，展示插页广告
     *      ■ 插页广告资源加载到，立即展示，广告关闭后自动跳转Blood Pressure-Result页
     *      ■ 插页广告资源未加载到，自动跳转至Blood Pressure-Result页
     */
    private fun loadAdmobInsertAd(vararg id: String) {
        AdMobInterstitialAdManager.setInterstitialAdListener(object : AdMobInterstitialAdListener {
            override fun onAdDismissedFullScreenContent() {
                startJumpActivity(id)
            }

            override fun onAdFailedToShowFullScreenContent() {
                startJumpActivity(id)
            }

            override fun onNotReady() {
                startJumpActivity(id)
            }

            override fun onAdShowedFullScreenContent() {
                if (id.isNotEmpty()) {
                    //点击Save按钮后_插页广告
                    AppsFlyerUtils.trackEvent("ad_inter_bp_new_save_show")
                    ATInterstitial.entryAdScenario(Constants.TOP_ON_INTER_ID, "f66471f8226a1a")
                    LogUtil.iTopOn("TopOn 配置的场景ID为: 【血压New页点击Save按钮后_插页广告】")
                } else {
                    //点击返回入口后_插页广告
                    AppsFlyerUtils.trackEvent("ad_inter_bp_new_back_show")
                    ATInterstitial.entryAdScenario(Constants.TOP_ON_INTER_ID, "f66471f678dfc6")
                    LogUtil.iTopOn("TopOn 配置的场景ID为: 【血压 New页点击返回入口后_插页广告】")
                }
            }
        })
        AdMobInterstitialAdManager.showInterstitialAd(this)
    }

    private fun startJumpActivity(id: Array<out String>) {
        //BpMainActivity销毁后，先启动BpMainActivity
//        startSplashActivity()
        if (id.isNotEmpty()) {
            val date =
                DateUtils.timestampToyyyyMMdd(viewModel.saveTimeMillis.value!!.toLong()).toLong()
            val intent = Intent(activity, BloodPressureResultActivity::class.java)
            intent.putExtra("type", Constants.BLOOD_PRESSURE_RECORD)
            intent.putExtra("date", date)
            intent.putExtra("bpdId", id[0])
            startActivity(intent)
        }
        finish()
    }

    @Deprecated("Deprecated in Java")
    override fun onBackPressed() {
//        loadAdmobInsertAd()
        loadTopOnInsertAd()
    }

    /**
     * 原生广告
     *     ■ 原生广告资源加载到，展示广告
     *     ■ 原生广告资源未加载到，隐藏广告位
     */
    private fun loadAdmobNativeAd() {
        AdMobNativeAdManager.setNativeAdListener(object : AdMobNativeAdListener {
            override fun onAdLoaded(loadedNativeAd: MutableList<NativeAd>) {
                setNativeAdView(loadedNativeAd)
            }

            override fun onAdImpression() {
                //原生广告埋点
                AppsFlyerUtils.trackEvent("ad_native_bp_new_show")
                AdMobNativeAdManager.removeUsedNativeAdListener()
            }
        })
        val nativeAdList = AdMobNativeAdManager.getNativeAds()
        if (nativeAdList.isNotEmpty()) {
            setNativeAdView(nativeAdList)
        } else {
            showGuide()
        }
    }

    private fun setNativeAdView(nativeAdList: MutableList<NativeAd>) {
        nativeAd = nativeAdList.first()
        binding.nativeAdContainer.setNativeAd(nativeAd)
        binding.nativeAdContainer.visibility = View.VISIBLE
        showGuide()
    }

    override fun onDestroy() {
        if (_binding != null) {
            binding.bannerAdContainer.removeAllViews()
        }
        toponBannerManager?.releaseBannerAd()
        TopOnInterAdManager.setManualLoadListener(null)
        super.onDestroy()
        nativeAd?.let { AdMobNativeAdManager.removeUsedNativeAd(it) }
    }


    private fun showGuide() {
        var jump = 0
        val options: HighlightOptions.Builder = HighlightOptions.Builder()
        val build = options.setRelativeGuide(
            RelativeGuide(
                R.layout.blood_pressure_record_guide_layout,
                Gravity.TOP,
                -UIHelperBp.getDimension(R.dimen.blood_pressure_bottom)
            )
        ).build()
        options.setOnClickListener {
            if (controller != null) {
                controller!!.remove()
            }
        }
        val page: GuidePage = GuidePage.newInstance().addHighLightWithOptions(
            binding.tvSave,
            HighLight.Shape.ROUND_RECTANGLE,
            UIHelperBp.getDimension(R.dimen.record_guide_round),
            0,
            build
        )
        NewbieGuide.with(this).setLabel("blood_pressure_record").alwaysShow(false)
            .addGuidePage(page).setOnGuideChangedListener(object : OnGuideChangedListener {
                override fun onShowed(controller: Controller?) {
                    this@BpBloodPressureNewRecordActivity.controller = controller
                }

                override fun onRemoved(controller: Controller?) {
                    if (jump == 0) {
                        this@BpBloodPressureNewRecordActivity.controller = null
                        jump++
                        saveBloodPressure()
                    }
                }
            }).build().show()
    }
}